package com.bifrost.service.impl;

import com.bifrost.common.base.ServerResponse;
import com.bifrost.common.model.ResultModel;
import com.bifrost.entity.Permission;
import com.bifrost.entity.Role;
import com.bifrost.entity.User;
import com.bifrost.model.param.RoleParam;
import com.bifrost.model.vo.PageVO;
import com.bifrost.model.vo.PermissionVO;
import com.bifrost.model.vo.RoleVO;
import com.bifrost.repository.AdminUserRepository;
import com.bifrost.repository.PermissionRepository;
import com.bifrost.repository.RoleRepository;
import com.bifrost.service.RoleService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service("roleService")
@Transactional
public class RoleServiceImpl implements RoleService {
    private static Logger log = LoggerFactory.getLogger(RoleServiceImpl.class);
    @Autowired
    RoleRepository roleRepository;
    @Autowired
    PermissionRepository permissionRepository;
    @Autowired
    AdminUserRepository adminUserRepository;

    @Override
    public ServerResponse add(Integer[] permissionIds, RoleParam roleParam) {
        Role role = Role.builder()
                .roleName(roleParam.getRoleName())
                .description(roleParam.getDescription())
                .build();
        role.setCreatedTimestamp(new Date());

        ServerResponse serverResponse = checkRoleNameExist(role,false);
        if(!serverResponse.isSuccess())//校验角色名称是否重复
            return serverResponse;
        if(ArrayUtils.isNotEmpty(permissionIds)) {
            //检查权限数据是否有效
            ServerResponse response = checkValid(permissionIds);
            if (!response.isSuccess())
                return ServerResponse.createByErrorMsg("分配的权限无效");
            role.setPermissions(new HashSet((List) response.getData()));
        }
        roleRepository.save(role);
        return ServerResponse.createBySuccessMsg("添加角色成功");
    }

    @Override
    public ResultModel delete(Integer roleId) {
        if (null == roleId)
            return ResultModel.error("参数错误");
        Role role = roleRepository.findOne(roleId);
        if (null == role)
            return ResultModel.error("该角色不存在");
        //获取该角色对应的用户
        Set<User> users = role.getUsers();
        if (CollectionUtils.isNotEmpty(users))
            for (User user : users)
                user.setRoles(null);//删除该用户对应的角色
        try {
            roleRepository.delete(role);//删除角色，由于role permission中间表由role维护，
        } catch (Exception e) {
            log.error("删除角色出错roleId:{},{}", roleId, e);
            return ResultModel.error("删除角色失败");
        }
        return ResultModel.ok("删除角色成功");
    }

    @Override
    public ServerResponse list(Integer currentPage,Integer pageSize,String roleName) {
        if (null == currentPage || null==pageSize)
            return ServerResponse.createByErrorMsg("参数错误");
        if(null != roleName)
            return select(currentPage,pageSize,roleName);
        int recordCount = new Long(roleRepository.count()).intValue();//查询一共有多少条记录
        if (0 == recordCount)
            return ServerResponse.createBySuccessMsg("没有角色数据");
        //Sort sort = new Sort(Sort.Direction.DESC,"rold_id")
        PageRequest pageRequest = new PageRequest(currentPage - 1, pageSize);//分页查询，前端页面开始为1，查询时开始为0
        Page<Role> page = roleRepository.findAll(pageRequest);
        if (null == page || CollectionUtils.isEmpty(page.getContent()))
            return ServerResponse.createBySuccessMsg("没有查询到对应的角色数据");
        PageVO vo = new PageVO(currentPage, pageSize, recordCount, page.getContent());
        return ServerResponse.createBySuccess(vo);
    }

    @Override
    public ServerResponse update(RoleParam roleParam, Integer[] permissonIds, User currentUser) {
        Role role = Role.builder()
                .id(roleParam.getId())
                .roleName(roleParam.getRoleName())
                .description(roleParam.getDescription())
                .build();
        role.setUpdatedBy(currentUser.getAdminName());
        role.setUpdatedTimestamp(new Date());
        ServerResponse serverResponse = checkRoleNameExist(role,true);
        if(!serverResponse.isSuccess())//校验角色名称是否重复
            return serverResponse;
        //1.校验是否存在该角色
        ServerResponse<Role> response = checkValid(role);
        if (!response.isSuccess())
            return response;
        if(ArrayUtils.isNotEmpty(permissonIds)) {
            //2.校验权限是否存在
            ServerResponse<List<Permission>> responseForPermission = checkValid(permissonIds);
            if (!responseForPermission.isSuccess())
                return responseForPermission;
            List<Permission> permissions = responseForPermission.getData();
            role.setPermissions(new HashSet<>(permissions));
        }
        Role retrive = roleRepository.save(role);
        if(null == retrive)
            return ServerResponse.createByErrorMsg("更新角色数据失败");

        return ServerResponse.createBySuccess("更新角色数据成功");
    }

    @Override
    public ServerResponse getDetail(Integer roleId) {
        if(null == roleId)
            return ServerResponse.createByErrorMsg("参数错误");
        Role role = roleRepository.findOne(roleId);
        if(null == role)
            return ServerResponse.createByErrorMsg("该用户不存在");
        Map<String,Object> map = new HashMap<>();
        List<Permission> permissionList = permissionRepository.findAll();//获取所有权限

        RoleVO roleVO = RoleVO.adapter(role);//组装roleVo
        roleVO.setPermissions(assemblePermissionVO(new ArrayList<>(role.getPermissions())));

        Set<PermissionVO> permissionsVO = assemblePermissionVO(permissionList);//组装permissionVO
        map.put("role",roleVO);
        map.put("permissions",permissionsVO);
        return ServerResponse.createBySuccess(map);
    }

    @Override
    public ServerResponse select(Integer currentPage,Integer pageSize,String roleName) {
        if(null == roleName)
            return ServerResponse.createBySuccess();
        //创建查询条件数据对象
        Role role = new Role();
        role.setRoleName(roleName);
        role.setCreatedTimestamp(null);
        //创建匹配器，即如何使用查询条件
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);//模糊查询% + str + %
        //创建实例
        Example<Role> ex = Example.of(role,matcher);
        Long recordCount = roleRepository.count(ex);//查询总的记录条数
        //查询
        PageRequest pageRequest = new PageRequest(currentPage - 1, pageSize);
        Page page = roleRepository.findAll(ex,pageRequest);
        if (null == page || CollectionUtils.isEmpty(page.getContent()))
            return ServerResponse.createBySuccessMsg("没有查询到对应的角色数据");
        PageVO vo = new PageVO(currentPage, pageSize, recordCount.intValue(), page.getContent());
        return ServerResponse.createBySuccess(vo);
    }

    @Override
    public ServerResponse batchDelete(Integer[] roleIds) {
        if(ArrayUtils.isEmpty(roleIds))
            return ServerResponse.createByErrorMsg("参数错误");
        //校验角色
        int[] ids = new int[roleIds.length];
        int index = -1;//[0,index]存储的是id
        for(int id : roleIds)
            ids[++index] = id;
        ServerResponse response = checkValid(ids);
        if(!response.isSuccess())
            return response;

        //消除外键依赖
        List<Role> roles = (List<Role>) response.getData();
        for(Role role : roles) {
            Set<User> users = role.getUsers();
            if(CollectionUtils.isNotEmpty(users)) {
                for(User user : users) {
                    user.getRoles().remove(role);
                }
            }
            adminUserRepository.save(users);
        }

        roleRepository.delete((List) response.getData());
        return ServerResponse.createBySuccess();
    }

    @Override
    public ServerResponse listForUserAdd() {
        List<Role> roleList = roleRepository.findAll();
        return ServerResponse.createBySuccess(roleList);
    }

    //===========================================================================

    /**
     * 校验是否存在该角色
     *
     * @param role
     * @return
     */
    public ServerResponse<Role> checkValid(Role role) {
        if (null == role || null == role.getId())
            return ServerResponse.createByErrorMsg("参数错误");
        Role dbrole = roleRepository.findOne(role.getId());
        return null == dbrole ? ServerResponse.createByErrorMsg("该角色不存在") : ServerResponse.createBySuccess(dbrole);
    }

    public ServerResponse<List<Role>> checkValid(int[] roleIds) {
        if (ArrayUtils.isEmpty(roleIds))
            return ServerResponse.createByErrorMsg("参数错误");
        List<Integer> ids = new ArrayList<>(roleIds.length);
        for (Integer id : roleIds)
            ids.add(id);
        List<Role> roleList = roleRepository.findAll(ids);
        if(CollectionUtils.isEmpty(roleList) || roleList.size() != roleIds.length)
            return ServerResponse.createByErrorMsg("角色不存在");
        return ServerResponse.createBySuccess(roleList);
    }


    /**
     * 校验权限是否有效存在
     *
     * @param permisssonIds
     * @return
     */
    public ServerResponse<List<Permission>> checkValid(Integer[] permisssonIds) {
        if (null == permisssonIds || 0 == permisssonIds.length)
            return ServerResponse.createByErrorMsg("参数错误");
        List<Integer> ids = new ArrayList<>(permisssonIds.length);
        for (Integer id : permisssonIds)
            ids.add(id);
        List<Permission> permissions = permissionRepository.findAll(ids);
        return CollectionUtils.isEmpty(permissions) || permissions.size() != permisssonIds.length ? ServerResponse.createByErrorMsg("权限不存在") : ServerResponse.createBySuccess(permissions);
    }


    /**
     * 使用角户名校验角色是否存在
     *
     * @param role
     * @param isUpdateOperation 表示校验用户存在是针对增加还是更新 true为更新
     * @return 如果存在，ServerResponse返回error message=“用户名已经被使用"
     */
    public ServerResponse checkRoleNameExist(Role role, boolean isUpdateOperation) {
        if (null == role || StringUtils.isEmpty(role.getRoleName()))
            return ServerResponse.createByErrorMsg("请确认角色名是否填写");
        Role role1 = roleRepository.findByRoleName(role.getRoleName());
        if (null == role1)//如果查询出来为空，那么该用户名一定没有重复
            return ServerResponse.createBySuccess();
        if (isUpdateOperation) {//如果是更新操作
            if (role.getId() == role1.getId()) {//如果查询出来的持有该用户名的是他自己，则证明用户名没有更改
                return ServerResponse.createBySuccess();
            }
        }
        return ServerResponse.createByErrorMsg("用户名已经被使用");
    }

    private Set<PermissionVO> assemblePermissionVO(List<Permission> permissionList) {
        Set<PermissionVO> set = new HashSet<>();
        Iterator<Permission> iterator = permissionList.iterator();
        while (iterator.hasNext()) {
            Permission permission = iterator.next();
            PermissionVO permissionVO = PermissionVO.adapter(permission);
            set.add(permissionVO);
        }
        return set;
    }

}
